# 导入相关包
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D
import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
from keras.utils import np_utils
from sklearn.model_selection import  train_test_split

#训练集所在的路径
train_dataset = (r'./tf_car_license_dataset/train_images/training-set')
#验证集所在的路径
validation_dataset = ('./tf_car_license_dataset/train_images/validation-set')
#所有测试集所在的路径
test_dataset = ('./tf_car_license_dataset/test_images')


def mo(data,seize=(32,32)):
    data=train_dataset
    size=(32,32)
    names=[]
    datas=[]
    labels=[]
    #遍历所有文件夹
    for subdir in os.listdir(data):
        subpath=os.path.join(data,subdir)
        #print('path',subpath)
        #判断文件夹是否存在
        if os.path.isdir(subpath):
            #获取每个文件夹的标签
            names.append(subdir)
            #遍历文件夹中的图片文件
            for filename in os.listdir(subpath):
                #对filename进行处理路径
                imgpath=data+'/'+subdir+'/'+filename
#                print(imgpath)
                img=cv2.imread(imgpath)
                #转为灰度图,路径问题
                resiz_img = cv2.resize(img, size,interpolation=cv2.INTER_LINEAR)
                #保存图片各像素
                #转为灰度图
                resize_image= cv2.cvtColor(resiz_img,cv2.COLOR_BGR2GRAY)
                img22 =resize_image .reshape((32, 32, 1))
                #保存数据
                datas.append(np.asarray(img22, dtype = np.int8))
                labels.append(subdir)
    return datas,labels

#调用函数读取数据
#数据集
all_data,all_label=mo(train_dataset)

#对图片大小进行调整
#转化数据类型
all_datas, all_labels = np.asarray(all_data, dtype = np.float32),np.asarray(all_label, dtype = np.int32)
#
##将标签转化为one_hot类型
ont_hot_labels = np_utils.to_categorical(all_labels)

#随机划分数据集
train_data, test_data, train_labels, test_labels =train_test_split(all_datas, 
                  ont_hot_labels,
                  test_size = 0.4)

#建立模型

model = Sequential()
  
# 一层卷积，卷积核是5*5，激活函数relu，padding='same'保证卷积核大小，不够补零，input_shape指定输入维度，(32,32,1)表示像素28的二维灰度图
model.add(Conv2D(filters=32,kernel_size=(5, 5),padding='same', input_shape=(32, 32, 1),activation='relu'))
# 最大池化层1，池化核大小2*2
model.add(MaxPool2D(pool_size=(2, 2)))

# 二层卷积
model.add(Conv2D(filters=64,kernel_size=(5, 5),padding='same', activation='relu'))
# 最大池化层2
model.add(MaxPool2D(pool_size=(2, 2)))

# 三层卷积
model.add(Conv2D(filters=128,kernel_size=(5, 5),padding='same', activation='relu'))
# 最大池化层3
model.add(MaxPool2D(pool_size=(2, 2)))

# 四层卷积
model.add(Conv2D(filters=256,kernel_size=(5, 5),padding='same', activation='relu'))
# 最大池化层4
model.add(MaxPool2D(pool_size=(2, 2)))

model.add(Dropout(0.25))
#flatten层，用于将多维的输入一维化，用于卷积层和全连接层的过渡
model.add(Flatten())  # 平坦层
#全连接，激活函数relu，添加隐藏层神经元的数量和激活函数
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.25)) 
#全连接，激活函数sigmoid
model.add(Dense(10, activation='softmax'))
#输出模型各层的参数状况
model.summary()

#from keras import optimizers
from tensorflow.keras import optimizers
#from tensorflow.keras.optimizers import SGD
#损失函数
model.compile(loss='categorical_crossentropy',
              optimizer=optimizers.SGD(lr = 0.01),
              metrics=['acc'])

#模型训练过程
history = model.fit(
      train_data,
      #在声明一个 epoch 完成并开始下一个epoch之前从generator产生的总步数（批次样本）
      # 它通常应该等于你的数据集的样本数量除以批量大小
      train_labels,
      # 整数。训练模型的迭代总轮数。
      epochs=10,
      #验证数据的生成器
      validation_data =(test_data,test_labels))

#测试损失值、测试集准确率；验证损失值、验证准确率
acc = history.history["acc"]   #测试集准确率
val_acc = history.history["val_acc"]   #验证集准确率
loss = history.history["loss"]   #训练的损失值
val_loss = history.history["val_loss"]   #验证损失值


#保存模型
model.save('model.h5')

'''
#加载模型
from keras.models import load_model
model = load_model('model.h5')
#使用模型进行预测
#随便选一张图进行识别




#随机使用一张图片进行检验
hj=cv2.imread(r'./tf_car_license_dataset/train_images/training-set/1/1509806878_75_5.bmp')
#转化图片大小32*32
hj1=cv2.resize(hj, (32,32),interpolation=cv2.INTER_LINEAR)
#转为灰度图
rey=np.asarray(cv2.cvtColor(hj1,cv2.COLOR_BGR2GRAY),dtype = np.int8)
img22 =rey.reshape((1,32, 32, 1))
#再转为浮点型
img23 = np.asarray(img22, dtype = np.float32)

#送入模型进行预测，同时输出图像
tu=model.predict(img23)
print('识别出来的数字是{}'.format(np.argmax(tu)))#返回最大概率坐标即为识别出来的数字
#画图进行检验
plt.imshow(hj)
'''





